#include <string.h>
#include <iostream>

using std::cout;
using std::endl;
using std::ostream;

class String
{
public:
    String();

    //显式调用该构造函数
    //禁止隐式转换
    //explicit  
    //对于String来说，是希望隐式转换能够正常进行的
    //所以不需要explicit关键字
    String(const char * );
    String(const String &);
    String & operator=(const String &);
    ~String();

    void print() const;

    const char * c_str() const {    return _pstr;   }

    size_t length() const { 
        //当传递空指针过来时，strlen会直接崩溃
        if(_pstr) {
            return strlen(_pstr);
        }
        return 0;
    }

    friend ostream & operator<<(ostream &os, const String & rhs);
private:
    char * _pstr;
};

ostream & operator<<(ostream &os, const String & rhs)
{
    os << rhs._pstr;
    return os;
}

String::String()
    : _pstr(nullptr)
{   
    cout << "String()" << endl; 
}

String::String(const char * pstr)
    : _pstr(new char[strlen(pstr) + 1]())
{
    cout << "String(const char*)" << endl;
    strcpy(_pstr, pstr);
}

String::String(const String & rhs)
    : _pstr(new char[strlen(rhs._pstr) + 1]())
{
    cout << "String(const String &)" << endl;
    strcpy(_pstr, rhs._pstr);
}

String & String::operator=(const String & rhs)
{
    cout << "operator=(const String&)" << endl;
    if(this != &rhs) {
        delete [] _pstr;
        _pstr = new char[strlen(rhs._pstr) + 1]();
        strcpy(_pstr, rhs._pstr);
    }
    return *this;
}

void String::print() const
{   
    //char* 的nullptr，由cout进行输出时，会导致程序直接崩溃
    //而且还没有报错信息
    if(_pstr) {
        cout << _pstr << endl;  
    }
}

String::~String()
{
    cout << "~String()" << endl;
    delete [] _pstr;
    _pstr = nullptr;
}

int main()
{
    //两个不一样的类型理论上来说，不应该直接赋值
    //String =  const char *
    String str1 = "Hello,world";
    cout << "s1:" << str1 << endl;

    String str2 = str1;
    cout << "s2:" << str2 << endl;

    return 0;
}

